"use client";
// 导入必要的 React 钩子和组件
import React, { useState, useEffect, useRef } from "react";
// 导入 AI 相关工具函数
import { generateText, tool } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
// 导入设置模态框组件
import { SettingsModal } from "./SettingsModal";
// 导入数据验证库
import { array, z } from "zod";
// 导入本地存储相关的工具函数
import {
  getApiKeyFromLocalStorage,
  getBaseURLFromLocalStorage,
  getSystemPromptFromLocalStorage,
  getModelFromLocalStorage,
} from "../../lib/settings";
// 导入机器人控制相关的类型和函数
import {
  JointState,
  UpdateJointDegrees,
  UpdateJointsDegrees,
} from "../../hooks/useRobotControl";

/**
 * 捕获网络摄像头图像并返回 JPEG 格式的 Data URL
 * @returns Promise<string> 返回图像的 base64 编码的 Data URL
 */
async function captureWebcamImage(): Promise<string> {
  return new Promise(async (resolve, reject) => {
    try {
      // 请求访问网络摄像头
      const stream = await navigator.mediaDevices.getUserMedia({ video: true });

      // 创建视频元素来播放视频流
      const video = document.createElement("video");
      video.srcObject = stream;
      video.play();

      video.onloadedmetadata = () => {
        // 创建画布并在准备就绪时绘制视频帧
        const canvas = document.createElement("canvas");
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;

        const context = canvas.getContext("2d");
        if (!context) return reject("无法获取画布上下文");

        // 将当前视频帧绘制到画布上
        context.drawImage(video, 0, 0, canvas.width, canvas.height);

        // 停止视频流
        stream.getTracks().forEach((track) => track.stop());

        // 获取 JPEG 格式的 Data URL
        const jpegDataUrl = canvas.toDataURL("image/jpeg", 0.9); // 0.0-1.0 质量范围
        resolve(jpegDataUrl);
      };
    } catch (err) {
      reject(err);
    }
  });
}

/**
 * 从文本中提取 JSON 数组
 * @param text 包含 JSON 代码块的文本
 * @returns number[][] | null 返回解析后的二维数组或 null
 */
function extractJsonArray(text: string): number[][] | null {
  // 匹配 ```json ... ``` 格式的代码块
  const match = text.match(/```json\s*([\s\S]*?)\s*```/);
  if (!match) {
    console.error("未找到 JSON 代码块");
    return null;
  }

  try {
    const jsonStr = match[1].trim();
    const parsed = JSON.parse(jsonStr);
    // 验证解析结果是否为二维数组
    if (Array.isArray(parsed) && parsed.every(Array.isArray)) {
      return parsed as number[][];
    } else {
      console.error("解析的 JSON 不是二维数组格式");
      return null;
    }
  } catch (e) {
    console.error("JSON 解析失败:", e);
    return null;
  }
}

/**
 * ChatControl 组件的属性接口
 */
type ChatControlProps = {
  /** 机器人名称 */
  robotName?: string;
  /** 系统提示词 */
  systemPrompt?: string;
  /** 更新关节角度的函数 */
  updateJointsDegrees: UpdateJointsDegrees;
};

/**
 * ChatControl 组件 - AI 控制机器人的聊天界面
 * @param props ChatControlProps 组件属性
 */
export function ChatControl({
  robotName,
  systemPrompt: configSystemPrompt,
  updateJointsDegrees: UpdateJointsDegrees,
}: ChatControlProps) {
  // 聊天输入框的状态
  const [input, setInput] = useState("");
  // 聊天消息历史记录
  const [messages, setMessages] = useState<{ sender: string; text: string }[]>([]);
  // 设置模态框的显示状态
  const [showSettings, setShowSettings] = useState(false);

  // 从本地存储获取 API 配置
  const apiKey = getApiKeyFromLocalStorage() || "";
  const baseURL = getBaseURLFromLocalStorage() || "https://api.openai.com/v1/";
  const model = getModelFromLocalStorage() || "gpt-4.1-nano";
  
  // 获取系统提示词，优先级：本地存储 > 配置参数 > 默认值
  const systemPrompt =
    getSystemPromptFromLocalStorage(robotName) ||
    configSystemPrompt ||
    `You can help control a robot by pressing keyboard keys. Use the keyPress tool to simulate key presses. Each key will be held down for 1 second by default. If the user describes roughly wanting to make it longer or shorter, adjust the duration accordingly.`;

  // 创建 OpenAI 实例
  const openai = createOpenAI({
    apiKey,
    baseURL,
  });

  /**
   * 处理用户命令
   * @param command 用户输入的命令文本
   */
  const handleCommand = async (command: string) => {
    // 添加用户消息到聊天记录
    setMessages((prev) => [...prev, { sender: "User", text: command }]);
    try {
      // 捕获摄像头图像
      const image = await captureWebcamImage();
      // 调用 AI 生成回复
      const result = await generateText({
        model: openai(model),
        messages: [
          {
            role: "user",
            content: [
              {
                type: "text",
                text: command,
              },
              {
                type: "image",
                image: image,
                // 图像部分的详细配置
              },
            ],
          },
        ],
      });
      
      // 处理 AI 回复文本
      let text = result.text.trim();
      const content = result.response?.messages[1]?.content;
      for (const element of content ?? []) {
        text += `\n\n${element}`;
      }
      // 添加 AI 回复到聊天记录
      setMessages((prev) => [...prev, { sender: "AI", text }]);
      
      // 解析回复中的 JSON 数组并更新机器人关节状态
      let arrays = extractJsonArray(text);
      if (arrays) {
        for (const array of arrays) {
          // 将数组转换为关节状态对象
          const jointStates = array.map((angle, index) => ({
            servoId: index,
            value: angle,
          }));

          // 更新关节角度
          UpdateJointsDegrees(jointStates);
          // 等待 100ms 后处理下一个命令
          await new Promise((resolve) => setTimeout(resolve, 100));
        }
      }
    } catch (error) {
      console.error("生成文本时出错:", error);
      setMessages((prev) => [
        ...prev,
        { sender: "AI", text: "错误：无法处理您的请求。" },
      ]);
    }
  };

  /**
   * 处理发送按钮点击事件
   */
  const handleSend = () => {
    if (input.trim()) {
      // 如果未设置 API 密钥，显示设置模态框
      if (!apiKey) {
        setShowSettings(true);
        return;
      }
      handleCommand(input.trim());
      setInput(""); // 发送后清空输入框
    }
  };

  /**
   * 处理输入框按键事件
   * @param e 键盘事件对象
   */
  const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      handleSend();
    }
  };

  return (
    <>
      {/* 聊天控制面板 */}
      <div className="fixed bottom-5 right-5 bg-zinc-900 bg-opacity-80 text-white p-4 rounded-lg shadow-lg w-80 z-50">
        {/* 标题栏 */}
        <h4 className="border-b border-zinc-600 pb-2 font-bold mb-2 flex items-center justify-between">
          <span>AI 机器人控制</span>
          <button
            onClick={() => setShowSettings(true)}
            className="ml-2 bg-zinc-700 hover:bg-zinc-600 text-white py-1 px-2 rounded text-sm"
          >
            设置
          </button>
        </h4>

        {/* 消息列表区域 */}
        <div className="mb-2 max-h-[60vh] overflow-y-auto">
          {messages.map((msg, idx) => (
            <div
              key={idx}
              className={`mb-2 ${
                msg.sender === "AI" ? "text-green-400" : "text-blue-400"
              }`}
            >
              <strong>{msg.sender === "AI" ? "AI" : "用户"}:</strong> {msg.text}
            </div>
          ))}
        </div>

        {/* 清除消息按钮 */}
        {messages.length > 0 && (
          <div className="mb-2 flex justify-end">
            <button
              onClick={() => setMessages([])}
              className="text-xs bg-zinc-700 hover:bg-zinc-600 text-white px-2 py-1 rounded"
            >
              清除对话
            </button>
          </div>
        )}

        {/* 输入区域 */}
        <div className="flex items-center space-x-2">
          <div className="relative flex items-center w-full">
            {/* 摄像头按钮 */}
            <button
              onClick={() => alert("摄像头功能即将推出")}
              className="absolute left-0 bg-zinc-700 hover:bg-zinc-600 text-zinc-400 p-2 rounded"
              title="打开摄像头"
            >
              <svg
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 24 24"
                fill="currentColor"
                className="w-5 h-5"
                aria-hidden="true"
              >
                <path d="M16 4C16.5523 4 17 4.44772 17 5V9.2L22.2133 5.55071C22.4395 5.39235 22.7513 5.44737 22.9096 5.6736C22.9684 5.75764 23 5.85774 23 5.96033V18.0397C23 18.3158 22.7761 18.5397 22.5 18.5397C22.3974 18.5397 22.2973 18.5081 22.2133 18.4493L17 14.8V19C17 19.5523 16.5523 20 16 20H2C1.44772 20 1 19.5523 1 19V5C1 4.44772 1.44772 4 2 4H16ZM15 6H3V18H15V6ZM7.4 8.82867C7.47607 8.82867 7.55057 8.85036 7.61475 8.8912L11.9697 11.6625C12.1561 11.7811 12.211 12.0284 12.0924 12.2148C12.061 12.2641 12.0191 12.306 11.9697 12.3375L7.61475 15.1088C7.42837 15.2274 7.18114 15.1725 7.06254 14.9861C7.02169 14.9219 7 14.8474 7 14.7713V9.22867C7 9.00776 7.17909 8.82867 7.4 8.82867ZM21 8.84131L17 11.641V12.359L21 15.1587V8.84131Z"></path>
              </svg>
            </button>

            {/* 命令输入框 */}
            <input
              type="text"
              value={input}
              onChange={(e) => setInput(e.target.value)}
              onKeyPress={handleKeyPress}
              onKeyDown={(e) => e.stopPropagation()}
              onKeyUp={(e) => e.stopPropagation()}
              placeholder="请输入控制命令..."
              className="flex-1 pl-10 p-2 rounded bg-zinc-700 text-white outline-none"
            />
          </div>
        </div>
      </div>

      {/* 设置模态框 */}
      <SettingsModal
        show={showSettings}
        onClose={() => setShowSettings(false)}
        robotName={robotName}
        systemPrompt={configSystemPrompt}
      />
    </>
  );
}
